﻿using Microsoft.Practices.Prism.Commands;
using System;
using System.Windows.Input;
using System.Xml;
using System.Xml.Serialization;
using System.Threading.Tasks;

namespace HobSoft.SoccerBet2014.Client.ViewModels
{
    using Domain.ClientService;
    using Common;
    using dmr = Domain.Models.BfRaw;
    [Serializable]
    [XmlRoot("runner")]
    public class Runner : CommandViewModel
    {
        #region command & imple
        public ICommand BlurCommand { get; protected set; }
        public ICommand FocusCommand { get; protected set; }
        public ICommand FilterCommand { get; protected set; }
        public ICommand BuyCommand { get; protected set; }
        public ICommand LayCommand { get; protected set; }
        public ICommand TransactionCommand { get; protected set; }

        public void DoTransaction(decimal? money)
        {
            if (!money.HasValue)
            {
                PublicLog.InfoFormat("投注额度必须大于1");
                return;
            }
            if (money.Value < 1)
            {
                PublicLog.InfoFormat("投注额度必须大于1");
                return;
            }

            Transaction.Money = money.Value;
            if (BfRequestService == null) return;
            var hasLogin = BfRequestService.HasLogin();
            Task.WaitAll(hasLogin);
            if (!hasLogin.Result)
            {
                PublicLog.InfoFormat("请登录必发账号");
                return;
            }
            RaiseCommandStart(TransactionCommand, "开始提交交易");
            dmr.PlaceInstruction placeIns = new dmr.PlaceInstruction();
            placeIns.Handicap = (double)Handicap;
            placeIns.SelectionId = SelectionID;
            placeIns.Side = Transaction.Side;
            placeIns.OrderType = dmr.OrderType.LIMIT;
            placeIns.LimitOrder = new dmr.LimitOrder()
            {
                Size = (double)Transaction.Money,
                Price = (double)Transaction.Price,
                PersistenceType = dmr.PersistenceType.LAPSE
            };



            BfRequestService.Betting(MarketID, placeIns, null).ContinueWith(t =>
            {
                BetApplication.Current.Dispatcher.Invoke(() =>
                {
                    RaiseCommandOver(TransactionCommand);
                    IsFocus = false;
                    if (t.Exception != null)
                        RaiseCommandError(t.Exception.InnerException);
                    if (t.IsCompleted)
                    {
                        if (t.Result != null)
                        {
                            if (t.Result.Status != dmr.ExecutionReportStatus.SUCCESS)
                            {
                                RaiseMessage("交易错误", t.Result.ErrorCode.ToString(), 5000);
                            }
                        }
                    }
                });
            });
        }

        protected void Buy(decimal? price)
        {
            Transaction.Side = dmr.Side.BACK;
            Transaction.Price = price.Value;
            IsFocus = true;
        }

        protected void Lay(decimal? price)
        {
            Transaction.Side = dmr.Side.LAY;
            Transaction.Price = price.Value;
            IsFocus = true;
        }

        protected void Filter()
        {
            IsFilter = true;
        }
        #endregion

        private bool _isFilter = false;
        [XmlIgnore]
        public bool IsFilter
        {
            get { return _isFilter; }
            set
            {
                PropertyValueChange(ref _isFilter, value, "IsFilter");
                if (_isFilter && IsFocus)
                    IsFocus = false;
            }
        }

        private bool _isFocus = false;
        [XmlIgnore]
        public bool IsFocus
        {
            get { return _isFocus; }
            set
            {
                PropertyValueChange(ref _isFocus, value, "IsFocus");
                if (!value)
                    Transaction.Money = 0m;
            }
        }


        private BfRunnerTransaction _transaction;
        [XmlIgnore]
        public BfRunnerTransaction Transaction
        {
            get { return _transaction; }
            protected set { PropertyValueChange(ref _transaction, value, "Transaction"); }
        }

        private BfMarket _market;
        [XmlIgnore]
        public BfMarket Market
        {
            get { return _market; }
            set { PropertyValueChange(ref _market, value, "Market"); }
        }

        private IBfRequestService _bfRequestService;
        public IBfRequestService BfRequestService
        {
            get
            {
                if (_bfRequestService == null && Market != null)
                    _bfRequestService = Market.BfRequestService;
                return _bfRequestService;
            }
            set
            {
                _bfRequestService = value;
            }
        }

        public Runner()
        {
            FilterCommand = new DelegateCommand(Filter);
            BuyCommand = new DelegateCommand<decimal?>(Buy);
            LayCommand = new DelegateCommand<decimal?>(Lay);
            TransactionCommand = new DelegateCommand<decimal?>(DoTransaction, (m) => this.IsFocus);
            FocusCommand = new DelegateCommand(() => this.IsFocus = true);
            BlurCommand = new DelegateCommand(() => this.IsFocus = false);
            RegisterCommand(FilterCommand, "关闭显示");
            RegisterCommand(BuyCommand, "创建订单-买");
            RegisterCommand(LayCommand, "创建订单-卖");
            RegisterCommand(TransactionCommand, "提交订单");
            RegisterCommand(FocusCommand, "获得焦点");
            RegisterCommand(BlurCommand, "失去焦点");
            Transaction = new BfRunnerTransaction();
            Transaction.PropertyChanged += Transaction_PropertyChanged;
        }

        void Transaction_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(e.PropertyName);
        }

        #region property model
        private int _eventID;
        [XmlIgnore]
        public int EventID
        {
            get { return _eventID; }
            set { PropertyValueChange(ref _eventID, value, "EventID"); }
        }

        private string _marketID;
        [XmlIgnore]
        public string MarketID
        {
            get { return _marketID; }
            set { PropertyValueChange(ref _marketID, value, "MarketID"); }
        }

        private int _selectionID;
        [XmlAttribute("selection-id")]
        public int SelectionID
        {
            get { return _selectionID; }
            set { PropertyValueChange(ref _selectionID, value, "SelectionID"); }
        }

        private string _runnerName;
        [XmlAttribute("name")]
        public string RunnerName
        {
            get { return _runnerName; }
            set { PropertyValueChange(ref _runnerName, value, "RunnerName"); }
        }

        private decimal _handicap;
        [XmlAttribute("handicap")]
        public decimal Handicap
        {
            get { return _handicap; }
            set { PropertyValueChange(ref _handicap, value, "Handicap"); }
        }

        private byte _orderIndex;
        [XmlAttribute("index")]
        public byte OrderIndex
        {
            get { return _orderIndex; }
            set { PropertyValueChange(ref _orderIndex, value, "OrderIndex"); }
        }

        private int _asianLineId;
        [XmlAttribute("asian-line-id")]
        public int AsianLineId
        {
            get { return _asianLineId; }
            set { PropertyValueChange(ref _asianLineId, value, "AsianLineId"); }
        }

        private decimal _totalMatched;
        [XmlAttribute("total-matched")]
        public decimal TotalMatched
        {
            get { return _totalMatched; }
            set { PropertyValueChange(ref _totalMatched, value, "TotalMatched"); }
        }

        private decimal _lastPrice;
        [XmlAttribute("last-price")]
        public decimal LastPrice
        {
            get { return _lastPrice; }
            set { PropertyValueChange(ref _lastPrice, value, "LastPrice"); }
        }

        private decimal _lP1;
        [XmlAttribute("lp1")]
        public decimal LP1
        {
            get { return _lP1; }
            set
            {
                PropertyValueChange(ref _lP1, value, "LP1");
                if (Transaction != null && !IsFocus)
                    Transaction.Price = _lP1;
            }
        }

        private decimal _lP2;
        [XmlAttribute("lp2")]
        public decimal LP2
        {
            get { return _lP2; }
            set { PropertyValueChange(ref _lP2, value, "LP2"); }
        }

        private decimal _lP3;
        [XmlAttribute("lp3")]
        public decimal LP3
        {
            get { return _lP3; }
            set { PropertyValueChange(ref _lP3, value, "LP3"); }
        }

        private decimal _bP1;
        [XmlAttribute("bp1")]
        public decimal BP1
        {
            get { return _bP1; }
            set { PropertyValueChange(ref _bP1, value, "BP1"); }
        }

        private decimal _bP2;
        [XmlAttribute("bp2")]
        public decimal BP2
        {
            get { return _bP2; }
            set { PropertyValueChange(ref _bP2, value, "BP2"); }
        }

        private decimal _bP3;
        [XmlAttribute("bp3")]
        public decimal BP3
        {
            get { return _bP3; }
            set { PropertyValueChange(ref _bP3, value, "BP3"); }
        }

        private decimal _lA1;
        [XmlAttribute("la1")]
        public decimal LA1
        {
            get { return _lA1; }
            set { PropertyValueChange(ref _lA1, value, "LA1"); }
        }

        private decimal _lA2;
        [XmlAttribute("la2")]
        public decimal LA2
        {
            get { return _lA2; }
            set { PropertyValueChange(ref _lA2, value, "LA2"); }
        }

        private decimal _lA3;
        [XmlAttribute("la3")]
        public decimal LA3
        {
            get { return _lA3; }
            set { PropertyValueChange(ref _lA3, value, "LA3"); }
        }

        private decimal _bA1;
        [XmlAttribute("ba1")]
        public decimal BA1
        {
            get { return _bA1; }
            set { PropertyValueChange(ref _bA1, value, "BA1"); }
        }

        private decimal _bA2;
        [XmlAttribute("ba2")]
        public decimal BA2
        {
            get { return _bA2; }
            set { PropertyValueChange(ref _bA2, value, "BA2"); }
        }

        private decimal _bA3;
        [XmlAttribute("ba3")]
        public decimal BA3
        {
            get { return _bA3; }
            set { PropertyValueChange(ref _bA3, value, "BA3"); }
        }
        #endregion
    }
}
